package com.borya.service.mobile.impl;

import com.alibaba.fastjson.JSONObject;
import com.borya.constant.RedisConstant;
import com.borya.dao.MerchantDAO;
import com.borya.dao.MerchantPerfectionServiceDAO;
import com.borya.dao.UserDAO;
import com.borya.framework.annotation.Autowired;
import com.borya.framework.annotation.Component;
import com.borya.model.db.*;
import com.borya.service.impl.BaseServiceImpl;
import com.borya.service.mobile.MerchantPerfectionService;
import com.borya.statuscode.StatusCode;
import com.borya.util.AliOSSUtil;
import com.borya.util.Constant;
import com.borya.util.DateUtils;
import com.borya.util.StringUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;

import java.time.Clock;
import java.util.Objects;


@Component("merchantPerfectionService")
public class MerchantPerfectionServiceImpl extends BaseServiceImpl implements MerchantPerfectionService {

    private Logger log = Logger.getLogger(getClass());

    @Autowired("merchantPerfectionServiceDAO")
    private MerchantPerfectionServiceDAO merchantPerfectionServiceDAO;

    @Autowired("merchantDAO")
    private MerchantDAO merchantDAO;

    @Autowired("userDAOImpl")
    private UserDAO userDAO;

    public UserDAO getUserDAO() {
        return userDAO;
    }

    @Override
    public String getPerfectionStatus(User user) {
        String merchantId = user.getMerchantId();
        String userId = user.getUserId();
        Integer livingStatus = 2; // 活体识别开关是否开启,1是，2否
        String identityCard = "", identityCardName = "", headPortrait = "";
        UserClientDetail userClient = merchantDAO.getUserClientByUserId(userId);
        if (Objects.isNull(userClient)) {
            log.error("商户详情不存在,merchantId=" + merchantId);
            return StatusCode.SYSTEM_EXCEPTION.toJSON("网络异常,商户查找异常");
        }

        // 1主账号0 子账号,子工号不可以做商户完善
        if (0 == userClient.getIsMain()) {
            UserClientDetail client = merchantDAO.getUserClientByDealerId(userClient.getDealerId(), 1);
            if (Objects.isNull(client)) {
                log.error("该子商户主工号信息不存在,dealerId=" + userClient.getDealerId());
                return StatusCode.SYSTEM_EXCEPTION.toJSON("网络异常,商户查找异常");
            }
            merchantId = client.getMerchantId();
        }

        Merchant merchant = merchantDAO.getByMerchantId(merchantId);
        if (Objects.isNull(merchant)) {
            log.error("商户不存在,merchantId=" + merchantId);
            return StatusCode.SYSTEM_EXCEPTION.toJSON("网络异常,商户查找异常");
        }
        UserClientDetail detail = merchantDAO.getUserClientDetailByMerchantId(userId);
        if (Objects.isNull(detail)) {
            log.error("商户详情不存在,userId=" + user.getUserId());
            return StatusCode.SYSTEM_EXCEPTION.toJSON("网络异常,商户查找异常");
        }
        String isPerfection = "2"; // 是否需要完善，1是，2否，3强制完善信息
        String operationType = "4"; // 操作类型，1需要完善身份证和门店地址信息,2需要完善身份证信息,3需要完善门店信息,4不需要完善
        boolean userRegion = StringUtil.isNULL(merchant.getUserRegion()); // 使用地址是否为空,true 是
        boolean identityCardData = false; // 身份证信息是否为空,true 是

        // 不是游客
        if (0L < merchant.getRegistTime()) {
            // 获取用户身份证相关信息
            livingStatus = detail.getLivingStatus();
            identityCardName = detail.getIdentityCardName();
            identityCard = detail.getIdentityCard();
            headPortrait = detail.getIdentifyPhotoHead();
            // 1主账号0 子账号
            if (0 == userClient.getIsMain()) {
                // 为1时，资料完善强制开关开启，才校验子工号相关信息，否则不校验
                if ("1".equals(Constant.PERFECTION_SWITCH)) {
                    identityCardData = StringUtil.isNULL(detail.getIdentityCard()) || StringUtil.isNULL(detail.getIdentityCardName());
                    if (userRegion) {
                        log.error("子工号不可以做商户完善,isMain:" + userClient.getIsMain() + ",merchantId:" + merchantId + ",userRegion:" + userRegion);
                        return StatusCode.PERMISSIONPROFILE_IS_NULL.toJSON("该商户主工号资料未完善，请联系主工号完善资料，谢谢合作！");
                    }
                    if (identityCardData) {
                        log.error("子工号不可以做商户完善,isMain:" + userClient.getIsMain() + ",merchantId:" + merchantId + ",identityCardData:" + identityCardData);
                        return StatusCode.PERMISSIONPROFILE_IS_NULL.toJSON("该子工号商户身份证信息资料未完善，请联系管理员，谢谢合作！");
                    }
                }
            } else {
                // 企业需要判断是否需要完善身份证信息，个人不需要
                if (1 == merchant.getMerchantType()) {
                    identityCardData = StringUtil.isNULL(detail.getIdentityCard()) || StringUtil.isNULL(detail.getIdentityCardName())
                            || StringUtil.isNULL(detail.getIdentityCardAddress());
                }
            }
            if (0 != userClient.getIsMain() && (userRegion || identityCardData)) {
                isPerfection = "1";
                // 为1时，资料完善强制开关开启
                if ("1".equals(Constant.PERFECTION_SWITCH)) {
                    isPerfection = "3";
                }
                if (userRegion) {
                    operationType = "3"; // 需要完善门店信息
                }
                if (identityCardData) {
                    operationType = "2"; // 需要完善身份证信息
                }
                if (userRegion && identityCardData) {
                    operationType = "1"; // 需要完善身份证和门店地址信息
                }
            }
        }

        JSONObject json = new JSONObject();
        json.put("isPerfection", isPerfection); // 是否需要完善资料
        json.put("operationType", operationType);// 需要完善类型，1需要完善身份证和门店地址信息,2需要完善身份证信息,3需要完善门店信息。
        json.put("similarity", Constant.LIMIT_SIMILARITY); // 活体识别最低相似度
        json.put("isSource", livingStatus); // 活体识别,1无源：自己上传照片对比，2：不做活体识别，3有源：公安部调取对比
        json.put("identityCard", identityCard); // 身份证号码
        json.put("identityCardName", identityCardName); // 身份证姓名
        json.put("headPortrait", headPortrait); // 身份证头像路径
        json.put("livingIdentifySwitch", 1 != livingStatus && 3 != livingStatus ? 2 : 1); // 活体识别开关是否开启,1是，2否
        log.info("获取是否需要资料完善、活体识别url:getPerfectionStatus,json" + json);
        return StatusCode.SUCCESS.toDiyJson("data", json);
    }

    @Override
    public String addPerfectionData(User user, JSONObject json) {
        final String merchantId = user.getMerchantId();
        final String userId = user.getUserId();
        final long nowTime = Clock.systemDefaultZone().millis();
        final String YYMMddHHmmss = DateUtils.format("YYMMddHHmmss");
        final String orderId = Constant.MERCHANT_PERFECTION_PREFIX + YYMMddHHmmss + StringUtil.randomNumberString(4);
        final String appType = json.getString("appType");
        final String identityCard = json.getString("identityCard");
        final String identityCardName = json.getString("identityCardName");
        final String identityCardAddress = json.getString("identityCardAddress");
        final String shopAddress = json.getString("shopAddress");
        final String shopSpecificAddress = json.getString("shopSpecificAddress").replaceAll(" ", "");
        final int operationType = json.getIntValue("operationType");
        final String identifyPhotoHead = json.getString("identifyPhotoHead"); // 身份证头像路径
        final String identifyPhotoFront = json.getString("identifyPhotoFront"); // 身份证正面照片地址
        final String identifyPhotoReverse = json.getString("identifyPhotoReverse"); // 身份背面面照片地址
        final String identifyPhotoHand = json.getString("identifyPhotoHand"); // 手持身份证照片地址
        final String period = json.getString("period"); // 身份证有效期
        Integer isAudit;// 是否需要预审，1是，2否

        if (0 == operationType) {
            log.error("param operationType is error");
            return StatusCode.PARAM_ERROR.toJSON("operationType不能为空");
        }
        // 需要完善身份证和门店地址信息或者只要完善门店信息
        if (1 == operationType || 3 == operationType) {
            if (StringUtil.isNULL(shopAddress)) {
                log.error("param shopAddress is error");
                return StatusCode.PARAM_ERROR.toJSON("门店地区不能为空");
            }
            if (StringUtil.isNULL(shopSpecificAddress)) {
                log.error("param shopSpecificAddress is error");
                return StatusCode.PARAM_ERROR.toJSON("具体地址不能为空");
            }
        }
        // 需要完善身份证和门店地址信息或者只要完善身份证信息
        if (1 == operationType || 2 == operationType) {
            if (StringUtil.isNULL(identityCard)) {
                log.error("param identityCard is error");
                return StatusCode.PARAM_ERROR.toJSON("身份证号码不能为空");
            }
            if (StringUtil.isNULL(identityCardName)) {
                log.error("param identityCardName is error");
                return StatusCode.PARAM_ERROR.toJSON("身份证姓名不能为空");
            }
            if (StringUtil.isNULL(identityCardAddress)) {
                log.error("param identityCardAddress is error");
                return StatusCode.PARAM_ERROR.toJSON("身份证地址不能为空");
            }
            if (StringUtil.isNULL(identifyPhotoHead)) {
                log.error("param identifyPhotoHead is error");
                return StatusCode.PARAM_ERROR.toJSON("身份证头像不能为空");
            }
            if (StringUtil.isNULL(identifyPhotoFront)) {
                log.error("param identifyPhotoFront is error");
                return StatusCode.PARAM_ERROR.toJSON("身份证正面照片不能为空");
            }
            if (StringUtil.isNULL(identifyPhotoReverse)) {
                log.error("param identifyPhotoReverse is error");
                return StatusCode.PARAM_ERROR.toJSON("身份证背面照片不能为空");
            }
            if (StringUtil.isNULL(identifyPhotoHand)) {
                log.error("param identifyPhotoHand is error");
                return StatusCode.PARAM_ERROR.toJSON("手持身份证照片不能为空");
            }
            if (StringUtil.isNULL(period)) {
                log.error("param period is error");
                return StatusCode.PARAM_ERROR.toJSON("身份证有效期不能为空");
            }
            // 暂时不需要校验身份证信息唯一性
//            Merchant userDetail = getUserDAO().getByDetailTypeAndIdentityCard(user.getDetailType(), identityCard, userId);
//            if (Objects.nonNull(userDetail)) {
//                log.warn("该商户身份证信息已存在,detailType is" + user.getDetailType());
//                return StatusCode.SYSTEM_EXCEPTION.toJSON("该商户身份证信息已存在");
//            }
        }
        Merchant merchant = merchantDAO.getByMerchantId(merchantId);
        if (merchant == null) {
            log.error("DB连接异常");
            return StatusCode.SYSTEM_EXCEPTION.toJSON();
        }

        MerchantPerfectionRecordInfo recordInfo = new MerchantPerfectionRecordInfo();
        recordInfo.setOrderId(orderId);
        recordInfo.setUserId(userId);
        recordInfo.setMerchantId(merchantId);
        recordInfo.setMerchantType(merchant.getMerchantType());
        recordInfo.setDealerId(merchant.getDealerId());
        recordInfo.setSource(appType);
        recordInfo.setIdentityCard(identityCard);
        recordInfo.setIdentityCardName(identityCardName);
        recordInfo.setIdentityCardAddress(identityCardAddress);
        recordInfo.setShopAddress(shopAddress);
        recordInfo.setShopSpecificAddress(shopSpecificAddress);
        recordInfo.setType(operationType); // 记录类型：1需要完善身份证和门店地址信息。2需要完善身份证信息。3需要完善门店信息。
        recordInfo.setAuditType(3); // 3自动审核
        if (StringUtils.isNotBlank(identityCard) && StringUtils.isNotBlank(identityCardName) && StringUtils.isNotBlank(identityCardAddress)) {
            // 需要走预审流程
            recordInfo.setStatus(2); // 2审核中
            recordInfo.setResult(0); // 0未审核
            recordInfo.setIdentifyPhotoHead(identifyPhotoHead);
            recordInfo.setIdentifyPhotoHand(identifyPhotoHand);
            recordInfo.setIdentifyPhotoFront(identifyPhotoFront);
            recordInfo.setIdentifyPhotoReverse(identifyPhotoReverse);
            recordInfo.setPeriod(period);
            isAudit = 1; // 需要预审
        } else {
            // 不需要预审
            recordInfo.setStatus(3); // 3审核完成
            recordInfo.setAuditTime(nowTime);
            recordInfo.setResult(1); // 1通过
            isAudit = 2; // 不需要预审
        }
        recordInfo.setCreateTime(nowTime);

        boolean bool = merchantPerfectionServiceDAO.insert(recordInfo);
        if (!bool) {
            log.error("数据库异常");
            return StatusCode.SYSTEM_EXCEPTION.toJSON();
        }

        if (StringUtils.isNotBlank(identityCard) && StringUtils.isNotBlank(identityCardName) && StringUtils.isNotBlank(identityCardAddress)) {
            MerchantPerfectionLogInfo info = new MerchantPerfectionLogInfo();
            info.setOrderId(orderId);
            info.setMerchantId(merchantId);
            info.setType(1); // 商户完善
            info.setAuditType(3); // 自动审核
            info.setSource("1");
            info.setIdentityCard(identityCard);
            info.setIdentityCardName(identityCardName);
            info.setIdentityCardAddress(identityCardAddress);
            info.setShopAddress(shopAddress);
            info.setShopSpecificAddress(shopSpecificAddress);
            info.setIdentifyPhotoHead(AliOSSUtil.generatePresignedUrl(AliOSSUtil.getDownloadUrl((identifyPhotoHead))));
            info.setIdentifyPhotoHand(AliOSSUtil.generatePresignedUrl(AliOSSUtil.getDownloadUrl((identifyPhotoHand))));
            info.setIdentifyPhotoFront(AliOSSUtil.generatePresignedUrl(AliOSSUtil.getDownloadUrl((identifyPhotoFront))));
            info.setIdentifyPhotoReverse(AliOSSUtil.generatePresignedUrl(AliOSSUtil.getDownloadUrl((identifyPhotoReverse))));
            info.setPeriod(period);
            info.setMerchantType(merchant.getMerchantType());
            info.setIsp("1");
            final String auditStr = JSONObject.toJSONString(info);

            // 商户资料完善需要加入redis自动审核
            Long result = merchantPerfectionServiceDAO.redis_rpush(RedisConstant.MQ_MERCHANT_PERFECTION_AUDITED_KEY, auditStr);
            if (result == null) {
                log.error("redis连接异常");
                return StatusCode.SYSTEM_EXCEPTION.toJSON();
            }
            log.info("商户资料完善预审： Redis(AMS) KEY:" + RedisConstant.MQ_MERCHANT_PERFECTION_AUDITED_KEY + ",val:" + auditStr);
        }

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("orderId", orderId); // 资料完善订单ID
        jsonObject.put("isAudit", isAudit);

        return StatusCode.SUCCESS.toDiyJson("data", jsonObject);
    }

    @Override
    public String getPerfectionResult(JSONObject json) {
        final String orderId = json.getString("orderId");
        if (StringUtil.isNULL(orderId)) {
            log.error("param orderId is error");
            return StatusCode.PARAM_ERROR.toJSON("orderId为空");
        }
        MerchantPerfectionRecordInfo info = merchantPerfectionServiceDAO.getByOrderId(orderId);
        if (Objects.isNull(info)) {
            log.error("该订单记录不存在,orderId=" + orderId);
            return StatusCode.SYSTEM_EXCEPTION.toJSON("网络异常,商户查找异常");
        }

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("result", null == info.getResult() ? 0 : info.getResult()); // 审核结果
        jsonObject.put("desc", info.getAutoAuditDesc()); // 审核结果

        return StatusCode.SUCCESS.toDiyJson("data", jsonObject);
    }

    @Override
    public String addLivingPreRecord(User user, JSONObject json) {
        final String merchantId = user.getMerchantId();
        final String similarity = json.getString("similarity"); // 活体识别相似度
        final String identifyPhoto = json.getString("identifyPhoto"); // 活体识别照片
        final String result = json.getString("result"); // 活体识别结果,1成功,2失败
        final String errorMsg = json.getString("errorMsg"); // 活体识别拒绝原因
        final String tencentOrderId = json.getString("tencentOrderId"); // 腾讯云orderId
        final String faceId = json.getString("faceId"); // 活体识别ID
        final String osType = json.getString("osType"); // 终端类型
        final String appType = json.getString("appType"); // app类型

        if (StringUtil.isNULL(similarity)) {
            log.error("param similarity is error");
            return StatusCode.PARAM_ERROR.toJSON("similarity为空");
        }
        if (StringUtil.isNULL(result)) {
            log.error("param result is error");
            return StatusCode.PARAM_ERROR.toJSON("result为空");
        }
        if ("2".equals(result) && StringUtil.isNULL(errorMsg)) {
            log.error("param errorMsg is error");
            return StatusCode.PARAM_ERROR.toJSON("errorMsg为空");
        }
        if (StringUtil.isNULL(tencentOrderId)) {
            log.error("param tencentOrderId is error");
            return StatusCode.PARAM_ERROR.toJSON("tencentOrderId为空");
        }
        if (StringUtil.isNULL(faceId)) {
            log.error("param faceId is error");
            return StatusCode.PARAM_ERROR.toJSON("faceId为空");
        }

        LoginLivingRecordInfo info = new LoginLivingRecordInfo();
        info.setSimilarity(similarity);
        info.setIdentifyPhoto(identifyPhoto);
        info.setRemark(errorMsg);
        info.setResult(result);
        info.setTencentOrderId(tencentOrderId);
        info.setUserId(user.getUserId());
        info.setTerminalType(osType);
        info.setAppType(appType);
        info.setDeviceName("腾讯云");
        info.setPhoneNo(user.getPhone());
        info.setFaceId(faceId);

        boolean bool = merchantPerfectionServiceDAO.addLivingPreRecord(info, merchantId, Constant.LIMIT_SIMILARITY);
        if (!bool) {
            log.error("数据库异常,merchantId:" + merchantId + ",info:" + info + ",limitSimilarity:" + Constant.LIMIT_SIMILARITY);
            return StatusCode.SYSTEM_EXCEPTION.toJSON();
        }

        return StatusCode.SUCCESS.toJSON();
    }
}